snapshot: Add infrastructure to snapshot CSS images
authorBenjamin Otte <otte@redhat.com>
Wed, 16 Nov 2016 19:51:53 +0000 (20:51 +0100)
committerBenjamin Otte <otte@redhat.com>
Wed, 16 Nov 2016 19:51:53 +0000 (20:51 +0100)
Use this infrastructure to render builtin images. Which means from now
on, GtkCheckbutton, GtkSpinner and a few others use snapshots.

gtk/gtkbuiltinicon.c
gtk/gtkcssimage.c
gtk/gtkcssimagebuiltin.c
gtk/gtkcssimagebuiltinprivate.h
gtk/gtkcssimageprivate.h
gtk/gtkiconhelper.c
gtk/gtkrendericon.c
gtk/gtkrendericonprivate.h
gtk/gtksnapshot.c

index ab294afc22871b9f40c60aa8efcaaca01236947c..547fc35a2aa788e0a7006b0b1cb0207230d6c512 100644 (file)
@@ -145,6 +145,26 @@ gtk_builtin_icon_draw (GtkCssGadget *gadget,
   return FALSE;
 }
 
+static gboolean
+gtk_builtin_icon_snapshot (GtkCssGadget *gadget,
+                           GtkSnapshot  *snapshot,
+                           int           x,
+                           int           y,
+                           int           width,
+                           int           height)
+{
+  GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (gadget));
+
+  gtk_snapshot_translate_2d (snapshot, x, y);
+  gtk_css_style_snapshot_icon (gtk_css_gadget_get_style (gadget),
+                               snapshot,
+                               width, height,
+                               priv->image_type);
+  gtk_snapshot_translate_2d (snapshot, -x, -y);
+
+  return FALSE;
+}
+
 static void
 gtk_builtin_icon_style_changed (GtkCssGadget      *gadget,
                                 GtkCssStyleChange *change)
@@ -165,6 +185,7 @@ gtk_builtin_icon_class_init (GtkBuiltinIconClass *klass)
   gadget_class->get_preferred_size = gtk_builtin_icon_get_preferred_size;
   gadget_class->allocate = gtk_builtin_icon_allocate;
   gadget_class->draw = gtk_builtin_icon_draw;
+  gadget_class->snapshot = gtk_builtin_icon_snapshot;
   gadget_class->style_changed = gtk_builtin_icon_style_changed;
 }
 
index 0f6c4e8862d837c75344f5d32ad12bd96f3f80de..81ab757a140d775c6572c18531c0fdfcc2168cd9 100644 (file)
@@ -95,6 +95,21 @@ gtk_css_image_real_transition (GtkCssImage *start,
     return _gtk_css_image_cross_fade_new (start, end, progress);
 }
 
+static void
+gtk_css_image_real_snapshot (GtkCssImage *image,
+                             GtkSnapshot *snapshot,
+                             double       width,
+                             double       height)
+{
+  cairo_t *cr;
+
+  cr = gtk_snapshot_append_cairo_node (snapshot,
+                                       &(graphene_rect_t)GRAPHENE_RECT_INIT (0, 0, width, height),
+                                       "Fallback<%s>", G_OBJECT_TYPE_NAME (image));
+  _gtk_css_image_draw (image, cr, width, height);
+  cairo_destroy (cr);
+}
+
 static void
 _gtk_css_image_class_init (GtkCssImageClass *klass)
 {
@@ -104,6 +119,7 @@ _gtk_css_image_class_init (GtkCssImageClass *klass)
   klass->compute = gtk_css_image_real_compute;
   klass->equal = gtk_css_image_real_equal;
   klass->transition = gtk_css_image_real_transition;
+  klass->snapshot = gtk_css_image_real_snapshot;
 }
 
 static void
@@ -240,6 +256,24 @@ _gtk_css_image_draw (GtkCssImage        *image,
   cairo_restore (cr);
 }
 
+void
+gtk_css_image_snapshot (GtkCssImage *image,
+                        GtkSnapshot *snapshot,
+                        double       width,
+                        double       height)
+{
+  GtkCssImageClass *klass;
+
+  g_return_if_fail (GTK_IS_CSS_IMAGE (image));
+  g_return_if_fail (snapshot != NULL);
+  g_return_if_fail (width > 0);
+  g_return_if_fail (height > 0);
+
+  klass = GTK_CSS_IMAGE_GET_CLASS (image);
+
+  klass->snapshot (image, snapshot, width, height);
+}
+
 void
 _gtk_css_image_print (GtkCssImage *image,
                       GString     *string)
index 3c045d9a558d0c39d8eddb70df718c0c1a0aac70..841ae91d26e1459a7c15e8e10748b9149374ed5e 100644 (file)
@@ -643,3 +643,31 @@ gtk_css_image_builtin_draw (GtkCssImage            *image,
   }
 }
 
+void
+gtk_css_image_builtin_snapshot (GtkCssImage            *image,
+                                GtkSnapshot            *snapshot,
+                                double                  width,
+                                double                  height,
+                                GtkCssImageBuiltinType  image_type)
+{
+  cairo_t *cr;
+
+  g_return_if_fail (GTK_IS_CSS_IMAGE (image));
+  g_return_if_fail (snapshot != NULL);
+  g_return_if_fail (width > 0);
+  g_return_if_fail (height > 0);
+
+  if (!GTK_IS_CSS_IMAGE_BUILTIN (image))
+    {
+      gtk_css_image_snapshot (image, snapshot, width, height);
+      return;
+    }
+
+  cr = gtk_snapshot_append_cairo_node (snapshot,
+                                       &(graphene_rect_t)GRAPHENE_RECT_INIT (0, 0, width, height),
+                                       "BuiltinImage<%d>", (int) image_type);
+  gtk_css_image_builtin_draw (image, cr, width, height, image_type);
+  cairo_destroy (cr);
+}
+
+
index 1ceeeff7ef00d34a42624839f68f442a72c6f96d..66c94d2f0ad8724ab122b6915ae5329c387e62b4 100644 (file)
@@ -57,6 +57,11 @@ void           gtk_css_image_builtin_draw                  (GtkCssImage
                                                             double                       width,
                                                             double                       height,
                                                             GtkCssImageBuiltinType       image_type);
+void           gtk_css_image_builtin_snapshot              (GtkCssImage                 *image,
+                                                            GtkSnapshot                 *snapshot,
+                                                            double                       width,
+                                                            double                       height,
+                                                            GtkCssImageBuiltinType       image_type);
 
 G_END_DECLS
 
index 912d0d784b9e05dce2633e7aacd1b475a2d1df92..492734cba281746a03712cfa3b637b246bf80eed 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "gtk/gtkcssparserprivate.h"
 #include "gtk/gtkcsstypesprivate.h"
+#include "gtk/gtksnapshotprivate.h"
 
 G_BEGIN_DECLS
 
@@ -74,6 +75,10 @@ struct _GtkCssImageClass
                                                     cairo_t                    *cr,
                                                     double                      width,
                                                     double                      height);
+  void         (* snapshot)                        (GtkCssImage                *image,
+                                                    GtkSnapshot                *snapshot,
+                                                    double                      width,
+                                                    double                      height);
   /* parse CSS, return TRUE on success */
   gboolean     (* parse)                           (GtkCssImage                *image,
                                                     GtkCssParser               *parser);
@@ -107,6 +112,10 @@ void           _gtk_css_image_draw                 (GtkCssImage                *
                                                     cairo_t                    *cr,
                                                     double                      width,
                                                     double                      height);
+void           gtk_css_image_snapshot              (GtkCssImage                *image,
+                                                    GtkSnapshot                *snapshot,
+                                                    double                      width,
+                                                    double                      height);
 void           _gtk_css_image_print                (GtkCssImage                *image,
                                                     GString                    *string);
 
index bd9a6f6bd18c6ed68dc41b781fdf7095fa9e23f6..98b036220055132af7bd3cbddaba9ebe8788f22a 100644 (file)
@@ -870,7 +870,7 @@ gtk_icon_helper_snapshot (GtkIconHelper *self,
  
   style = gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self)));
 
-  gtk_css_style_snapshot_icon (style, snapshot, texture);
+  gtk_css_style_snapshot_icon_texture (style, snapshot, texture);
 }
 
 gboolean
index cd43ec9ecb9e6ff9a85c1c82272158a0e59b0151..8ed65e0d9d11d93989d48398799d1773ffdd4b59 100644 (file)
@@ -82,6 +82,52 @@ gtk_css_style_render_icon (GtkCssStyle            *style,
   cairo_set_matrix (cr, &saved_matrix);
 }
 
+void
+gtk_css_style_snapshot_icon (GtkCssStyle            *style,
+                             GtkSnapshot            *snapshot,
+                             double                  width,
+                             double                  height,
+                             GtkCssImageBuiltinType  builtin_type)
+{
+  const GtkCssValue *shadows, *transform;
+  cairo_matrix_t transform_matrix;
+  graphene_matrix_t matrix, other, saved_matrix;
+  GtkCssImage *image;
+
+  g_return_if_fail (GTK_IS_CSS_STYLE (style));
+  g_return_if_fail (snapshot != NULL);
+
+  image = _gtk_css_image_value_get_image (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SOURCE));
+  if (image == NULL)
+    return;
+
+  shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
+  transform = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM);
+
+  if (!_gtk_css_transform_value_get_matrix (transform, &transform_matrix))
+    return;
+
+  graphene_matrix_init_from_matrix (&saved_matrix, gtk_snapshot_get_transform (snapshot));
+
+  /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
+  graphene_matrix_init_translate (&matrix, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(width / 2.0, height / 2.0, 0));
+  graphene_matrix_init_from_2d (&other, transform_matrix.xx, transform_matrix.yx,
+                                        transform_matrix.xy, transform_matrix.yy,
+                                        transform_matrix.x0, transform_matrix.y0);
+  graphene_matrix_multiply (&other, &matrix, &matrix);
+  graphene_matrix_init_translate (&other, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(- width / 2.0, - height / 2.0, 0));
+  graphene_matrix_multiply (&matrix, &other, &matrix);
+  gtk_snapshot_transform (snapshot, &matrix);
+
+  if (!_gtk_css_shadows_value_is_none (shadows))
+    {
+      g_warning ("Painting shadows not implemented for textures yet.");
+    }
+  gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type);
+
+  gtk_snapshot_set_transform (snapshot, &saved_matrix);
+}
+
 static gboolean
 get_surface_extents (cairo_surface_t *surface,
                      GdkRectangle    *out_extents)
@@ -224,9 +270,9 @@ gtk_css_style_render_icon_get_extents (GtkCssStyle  *style,
 }
 
 void
-gtk_css_style_snapshot_icon (GtkCssStyle *style,
-                             GtkSnapshot *snapshot,
-                             GskTexture  *texture)
+gtk_css_style_snapshot_icon_texture (GtkCssStyle *style,
+                                     GtkSnapshot *snapshot,
+                                     GskTexture  *texture)
 {
   const GtkCssValue *shadows, *transform;
   cairo_matrix_t transform_matrix;
index 83a3b04cc6e160c654ff244b0ace8755b4b56f4b..8b12d135bb2af1255515de066ceff173b2ba97a3 100644 (file)
@@ -37,13 +37,18 @@ void    gtk_css_style_render_icon               (GtkCssStyle            *style,
                                                  double                  width,
                                                  double                  height,
                                                  GtkCssImageBuiltinType  builtin_type);
+void    gtk_css_style_snapshot_icon             (GtkCssStyle            *style,
+                                                 GtkSnapshot            *snapshot,
+                                                 double                  width,
+                                                 double                  height,
+                                                 GtkCssImageBuiltinType  builtin_type);
 
 void    gtk_css_style_render_icon_surface       (GtkCssStyle            *style,
                                                  cairo_t                *cr,
                                                  cairo_surface_t        *surface,
                                                  double                  x,
                                                  double                  y);
-void    gtk_css_style_snapshot_icon             (GtkCssStyle            *style,
+void    gtk_css_style_snapshot_icon_texture     (GtkCssStyle            *style,
                                                  GtkSnapshot            *snapshot,
                                                  GskTexture             *texture);
 
index 7a7fd6653ccc6c94b77db6dedeb8c9bf35f53356..3f2fd4b93b8e76d328cec57039c9d1da0687099d 100644 (file)
@@ -402,9 +402,9 @@ gtk_snapshot_render_icon (GtkSnapshot     *snapshot,
 
   texture = gsk_texture_new_for_pixbuf (pixbuf);
   gtk_snapshot_translate_2d (snapshot, x, y);
-  gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
-                               snapshot,
-                               texture);
+  gtk_css_style_snapshot_icon_texture (gtk_style_context_lookup_style (context),
+                                       snapshot,
+                                       texture);
   gtk_snapshot_translate_2d (snapshot, -x, -y);
   gsk_texture_unref (texture);
 }